package com.wuze.cloud.service.impl;

import com.wuze.cloud.adapter.SysStorageAdapter;
import com.wuze.cloud.context.RedisContext;
import com.wuze.cloud.context.UserContext;
import com.wuze.cloud.dao.SysFileDao;
import com.wuze.cloud.dao.SysStorageDao;
import com.wuze.cloud.dao.SysUserDao;
import com.wuze.cloud.exception.SysGlobalException;
import com.wuze.cloud.model.SysRegisterData;
import com.wuze.cloud.model.SysUploadData;
import com.wuze.cloud.pojo.SysFileDO;
import com.wuze.cloud.pojo.SysStorageDO;
import com.wuze.cloud.pojo.SysUserDO;
import com.wuze.cloud.request.SysUpdateSpaceQuery;
import com.wuze.cloud.response.SysStorageInfoAdminVO;
import com.wuze.cloud.response.SysStorageInfoVO;
import com.wuze.cloud.service.SysStorageService;
import com.wuze.cloud.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.wuze.cloud.enums.SysFileTypeEnum.*;
import static com.wuze.cloud.enums.SysGlobalExceptionEnum.SPACE_NOT_ENOUGH;
import static com.wuze.cloud.enums.SysGlobalExceptionEnum.USER_AUTH_ERR;
import static com.wuze.cloud.enums.SysUserRoleEnum.ROOT;
import static com.wuze.cloud.enums.SysUserRoleEnum.SIMPLE;

/**
 * @author: wuze
 * @description:
 * @date: 2023/02/28
 */
@Service
@Slf4j
public class SysStorageServiceImpl implements SysStorageService {

    @Autowired
    private SysStorageDao storageDao;

    @Autowired
    private SysStorageAdapter storageAdapter;

    @Autowired
    private SysUserDao userDao;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SysFileDao fileDao;



    private static final Long UNIT_GB = (long) (1024*1024*1024);

    /**
     * 用户获取存储信息
     * @return
     */
    @Override
    public SysStorageInfoVO getInfo() {
        SysUserDO user = UserContext.getUser();
        SysStorageInfoVO vo = (SysStorageInfoVO)redisUtil.get(RedisContext.USER_KEY + user.getId());
        if(Objects.nonNull(vo)){
            return vo;
        }

        SysStorageDO storage = storageDao.findByUserId(user.getId());
        vo = storageAdapter.buildSysStorageInfoVO(storage);
        redisUtil.set(RedisContext.USER_KEY+user.getId(), vo);
        return vo;
    }

    /**
     * 管理员获取存储信息
     * @param top
     * @return
     */
    @Override
    public List<SysStorageInfoAdminVO> getInfoAdmin(Integer top) {
        //鉴权
        SysUserDO user = UserContext.getUser();
        if (!user.getRole().equals(ROOT.getCode())) {
            throw new SysGlobalException(USER_AUTH_ERR.getCode(), USER_AUTH_ERR.getMsg());
        }
        List<SysStorageInfoAdminVO> vos = (List<SysStorageInfoAdminVO>) redisUtil.get(RedisContext.KEY+":"+top);
        if(!CollectionUtils.isEmpty(vos)){
            return vos;
        }
        List<SysStorageDO> storages = storageDao.selectTop(top);

        vos = storageAdapter.buildSysStorageInfoAdminVO(storages);

        redisUtil.set(RedisContext.KEY+":"+top,vos);

        return vos;
    }

    /**
     * 上传文件内修改存储信息
     * @param file
     */
    @Override
    public void updateStorageInfo(SysFileDO file) {
        SysStorageDO storage = storageDao.findByUserId(file.getUserId());
        if (file.getType().equals(DOCUMENT_FILE.name())) {
            storage.setDocumentSize(storage.getDocumentSize() + file.getSize());
        }
        if (file.getType().equals(IMAGE_FILE.name())) {
            storage.setImageSize(storage.getImageSize() + file.getSize());
        }
        if (file.getType().equals(VIDEO_FILE.name())) {
            storage.setVideoSize(storage.getVideoSize() + file.getSize());
        }
        if (file.getType().equals(OTHER_FILE.name())) {
            storage.setOrtherSize(storage.getOrtherSize() + file.getSize());
        }
        storage.setCurrSize(storage.getCurrSize() + file.getSize());
        if (storage.getCurrSize() > storage.getMaxSize()) {
            throw new SysGlobalException(SPACE_NOT_ENOUGH.getCode(), SPACE_NOT_ENOUGH.getMsg());
        }
        storageDao.update(storage);
    }

    /**
     * 管理员扩充空间
     * @param query
     */
    @Override
    public void dilatation(SysUpdateSpaceQuery query) {
        //鉴权
        SysUserDO user = UserContext.getUser();
        if (!user.getRole().equals(ROOT.getCode())) {
            throw new SysGlobalException(USER_AUTH_ERR.getCode(), USER_AUTH_ERR.getMsg());
        }
        //修改存储
        SysStorageDO storage = storageDao.findByUserId(query.getUserId());
        storage.setMaxSize(storage.getMaxSize() + gbTob(query.getNum()));
        storageDao.update(storage);
        log.info("扩充记录：操作人id:{}、用户id：{}、扩充容量：{}GB",
                user.getId(), storage.getUserId(), query.getNum());
    }

    /**
     * 管理员缩减空间
     * @param query
     */
    @Override
    public void reduction(SysUpdateSpaceQuery query) {
        //鉴权
        SysUserDO user = UserContext.getUser();
        if (!user.getRole().equals(ROOT.getCode())) {
            throw new SysGlobalException(USER_AUTH_ERR.getCode(), USER_AUTH_ERR.getMsg());
        }
        //修改存储
        SysStorageDO storage = storageDao.findByUserId(query.getUserId());
        storage.setMaxSize(storage.getMaxSize() - gbTob(query.getNum()));
        if(storage.getCurrSize()>=storage.getMaxSize()){
            throw new SysGlobalException(SPACE_NOT_ENOUGH.getCode(),SPACE_NOT_ENOUGH.getMsg());
        }
        storageDao.update(storage);
        log.info("缩减记录：操作人id:{}、用户id：{}、缩减容量：{}GB", user.getId(), storage.getUserId(), query.getNum());

    }

    /**
     * GB转字节B
     * @param num
     * @return
     */
    private Long gbTob(Integer num) {
        return num*UNIT_GB;
    }


}
